'''
生物建模与仿真
课程实践1
拟合代码

'''

'''
import cv2
import numpy as np
from scipy.interpolate import splprep, splev
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 读取图像并提取轮廓
image = cv2.imread('/mnt/c/Personal_Profiles/python/Biological_modeling/outline.png', cv2.IMREAD_GRAYSCALE)
_, thresh = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# 选择最大的轮廓
contour = max(contours, key=cv2.contourArea)
contour = contour.squeeze()

# 插值
tck, u = splprep([contour[:, 0], contour[:, 1]], s=0)
u_new = np.linspace(u.min(), u.max(), 200)
x_new, y_new = splev(u_new, tck)

# 绘制结果
plt.figure()
plt.imshow(image, cmap='gray')
plt.plot(x_new, y_new, 'r-', label='Interpolated')
plt.scatter(contour[:, 0], contour[:, 1], s=1, label='Original', color='yellow')
plt.legend()
plt.show()



# 定义拟合函数（例如，椭圆）
def ellipse(t, a, b, phi, x0, y0):
    return (a * np.cos(t + phi) + x0, b * np.sin(t + phi) + y0)

# 计算参数
t = np.linspace(0, 2*np.pi, len(contour))
x, y = contour[:, 0], contour[:, 1]
params, _ = curve_fit(ellipse, t, np.vstack((x, y)))

# 生成拟合曲线
t_fit = np.linspace(0, 2*np.pi, 200)
x_fit, y_fit = ellipse(t_fit, *params)

# 绘制结果
plt.figure()
plt.imshow(image, cmap='gray')
plt.plot(x_fit, y_fit, 'b-', label='Fitted')
plt.scatter(contour[:, 0], contour[:, 1], s=1, label='Original', color='yellow')
plt.legend()
plt.show()
'''
import cv2
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt

# 读取图像并提取轮廓
image = cv2.imread('/mnt/c/Personal_Profiles/python/Biological_modeling/outline.png', cv2.IMREAD_GRAYSCALE)
_, thresh = cv2.threshold(image, 50, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contour = max(contours, key=cv2.contourArea).squeeze()

# 定义拟合函数（例如，椭圆）
def ellipse(t, a, b, phi, x0, y0):
    x = a * np.cos(t + phi) + x0
    y = b * np.sin(t + phi) + y0
    return x, y

# 将(x, y)数据展平
x, y = contour[:, 0], contour[:, 1]
t = np.linspace(0, 2*np.pi, len(contour))

# 拟合参数
def fit_func(t, a, b, phi, x0, y0):
    x, y = ellipse(t, a, b, phi, x0, y0)
    return np.concatenate((x, y))

# 初始参数猜测
initial_guess = (100, 50, 0, np.mean(x), np.mean(y))

# 拟合数据
params, _ = curve_fit(fit_func, t, np.concatenate((x, y)), p0=initial_guess)

# 生成拟合曲线
t_fit = np.linspace(0, 2*np.pi, 200)
x_fit, y_fit = ellipse(t_fit, *params)

# 绘制结果
plt.figure()
plt.imshow(image, cmap='gray')
plt.plot(x_fit, y_fit, 'b-', label='Fitted')
plt.scatter(contour[:, 0], contour[:, 1], s=1, label='Original', color='yellow')
plt.legend()
plt.show()